# Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of "Eclipse Public License v1.0"
# which accompanies this distribution, and is available
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
# Initial Contributors:
# Nokia Corporation - initial contribution.
#
# Contributors:
#
# Description:
# stringtable.pl - Makes a string table .cpp and .h file from a .st file
# This tool takes a valid .st file as an input parameter and converts it into a .h and a .cpp file
# 
#

use strict;

# Removes the extension from the filename
$ARGV[0] =~ m/(.*)\..*/;
my $root = $1;
$root =~ m/(.*[\\\/])([^\\\/]*)$/;

my $path_to_file = ("$1");
my $filename = lc("$2");
my $header_to_include = lc("$filename.h");

# Open the input filename
open (IN, "<$ARGV[0]" ) or die ("Error: $ARGV[0] $!");

# Parse header comments
my $input;
my @comments;
while ($input = <IN>) {
	# Comments starting with '#' not to be included in header file
	next if ($input =~ /^\s*\#/);  

	chomp($input);

	# Save comments containing '!' or stop looking if something else is found
	if ($input =~ /\!(.*)/) {
		push(@comments, "$1\n");
  	} else {
    		last;
  	}
}

my $folding;
# Check that line is of the right format and get the table name.
$input =~ m/(f*stringtable) ([A-Za-z0-9_]+)/ or die ("Error: $ARGV[0] is not a stringtable file");
my $name = $2;
if ($1 eq "stringtable") {
	$folding = "ETrue";
	} else {
	$folding = "EFalse";
	}

# Open the output filenames
open (CPP, ">"."$path_to_file"."$filename".".cpp" ) or die ("Error: $ARGV[0] Can't open cpp file");
open (HEADER, ">"."$path_to_file"."$filename".".h" ) or die ("Error: $ARGV[0] Can't open header file");

my $sourcename = $ARGV[0];
$sourcename =~ s/^(.*epoc32)/epoc32/i;

# Output the preambles
print CPP <<EOD;
// Autogenerated from $sourcename by the stringtable tool - Do not edit
#include <e32std.h>
#include <stringpool.h>
#include <stringtablesupport.h>
#include "$header_to_include"
#ifdef _DEBUG
#undef _DEBUG
#endif

EOD

print HEADER <<EOD;
// Autogenerated from $sourcename by the stringtable tool - Do not edit

#ifndef STRINGTABLE_$name
#define STRINGTABLE_$name

#include <stringpool.h>

struct TStringTable;

EOD

# If there are no header comments, use the default comment, otherwise, add the header comments
if (@comments == 0) {
	print HEADER "/** A String table */\n";
	} else {
	print HEADER @comments;
	}

print HEADER <<EOD;
class $name 
	{
public:
	enum TStrings
		{
EOD

my $count = 0;
my $outputcomma = 0;
my @commentlines;

#Now process file
until (eof IN) {
    # Treat lines with a '#' as the first character as comments and skip them, ignoring 0 or more whitespaces before it.
    # If # is not the first character, then treat them as part of the string.
    do 
      {
      $input = readline (*IN);
	    chomp($input);
      } while ($input =~ m/^\s*\#/);

	if ($input =~ m/\!(.*)/) {
		# Save lines that start with '!' to print later
		push(@commentlines, "\t\t$1\n");
	} else {
		# Parse the line
		$input =~ m/([A-Za-z0-9]+)\s*(.*)/ or die ("Error: $ARGV[0] badly formed at \"$input\"");

		# If a comma needs to be printed, print it
		if ($outputcomma == 1) {
			print HEADER ",\n";
			$outputcomma = 0;
		}
		# Print pending comments and clear the comments array
		if (@commentlines > 0) {
			print HEADER @commentlines;
			@commentlines = '';
		}

		# Form a version of the string that can go in a comment. This
		# can't contain /* or */
		my $enum = $1;
		my $string = $2;
		$string =~ s/\s+$//;	# remove any trailing whitespace
		my $comment = $string;
		$comment =~ s|/\*|/ \*|g;
		$comment =~ s|\*/|\* /|g;

		# Increment the count
		$count++;
		print HEADER "\t\t/** $comment */\n";
		print HEADER "\t\t$enum";
		print CPP "_STLIT8(K$count, \"$string\");\n";
		$outputcomma = 1;
	}
}

# Print closing comments
if (@commentlines > 0) {
	print HEADER "\n";
	print HEADER @commentlines;
	@commentlines = '';
} else {
	print HEADER "\n";
}

#Output intermediate boilerplate in the cpp
print CPP <<EOD;

// Intermediate
const void * const KStringPointers[] =
	{
EOD

# And the end of the headers
print HEADER <<EOD;
		};
	static const TStringTable Table;	
	};

#endif // STRINGTABLE_$name

EOD

#Output the table of pointers to the cpp file
my $total = $count;

for ($count = 1; $count <= $total ; $count++) {
    if ($count > 1) {
	print CPP ",\n";
    }
    print CPP "\t(const void*)&K$count";
};

#The last of the boilerplate
print CPP <<EOD;

	};

const TStringTable ${name}::Table = {$total, KStringPointers, $folding};
EOD
